﻿using System.Collections.Generic;
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Linq;
using System.Windows.Shapes;

namespace BlankApp1.Views
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private Button[,] buttons;
        private Point? startPoint;
        private Point? endPoint;
        private string currentMode = "";
        private const int GridSize = 20;
        private double buttonSize; // 添加按钮大小属性

        public MainWindow()
        {
            InitializeComponent();
            InitializeGrid();
        }

        private void InitializeGrid()
        {
            buttons = new Button[GridSize, GridSize];

            // 计算按钮大小
            buttonSize = gridMap.ActualWidth / GridSize;

            for (int i = 0; i < GridSize; i++)
            {
                for (int j = 0; j < GridSize; j++)
                {
                    var button = new Button
                    {
                        Background = Brushes.White,
                        Margin = new Thickness(1),
                        Width = buttonSize,
                        Height = buttonSize
                    };
                    button.Click += Grid_Button_Click;
                    buttons[i, j] = button;
                    gridMap.Children.Add(button);
                }
            }
        }

        private void Grid_Button_Click(object sender, RoutedEventArgs e)
        {
            var button = sender as Button;
            int row = -1, col = -1;

            // 找到被点击的按钮在网格中的位置
            for (int i = 0; i < GridSize; i++)
            {
                for (int j = 0; j < GridSize; j++)
                {
                    if (buttons[i, j] == button)
                    {
                        row = i;
                        col = j;
                        break;
                    }
                }
            }

            if (row == -1 || col == -1) return;

            switch (currentMode)
            {
                case "Start":
                    // 清除之前的起点
                    if (startPoint.HasValue)
                    {
                        buttons[(int)startPoint.Value.X, (int)startPoint.Value.Y].Background = Brushes.White;
                    }
                    button.Background = Brushes.Green;
                    startPoint = new Point(row, col);
                    break;

                case "End":
                    // 清除之前的终点
                    if (endPoint.HasValue)
                    {
                        buttons[(int)endPoint.Value.X, (int)endPoint.Value.Y].Background = Brushes.White;
                    }
                    button.Background = Brushes.Red;
                    endPoint = new Point(row, col);
                    break;

                case "Wall":
                    // 切换障碍物状态
                    if (button.Background == Brushes.Black)
                    {
                        button.Background = Brushes.White;
                    }
                    else
                    {
                        button.Background = Brushes.Black;
                    }
                    break;
            }
        }

        private List<Node> FindPath(Point start, Point end)
        {
            var openList = new List<Node>();
            var closedList = new List<Node>();
            var startNode = new Node((int)start.X, (int)start.Y);
            var endNode = new Node((int)end.X, (int)end.Y);

            openList.Add(startNode);

            while (openList.Count > 0)
            {
                var currentNode = openList.OrderBy(x => x.F).First();

                if (currentNode.X == endNode.X && currentNode.Y == endNode.Y)
                {
                    return GetPath(currentNode);
                }

                openList.Remove(currentNode);
                closedList.Add(currentNode);

                foreach (var neighbor in GetNeighbors(currentNode))
                {
                    if (closedList.Any(x => x.X == neighbor.X && x.Y == neighbor.Y))
                        continue;

                    var gCost = currentNode.G + 1;

                    if (!openList.Any(x => x.X == neighbor.X && x.Y == neighbor.Y))
                    {
                        neighbor.G = gCost;
                        neighbor.H = CalculateHCost(neighbor, endNode);
                        neighbor.Parent = currentNode;
                        openList.Add(neighbor);
                    }
                    else if (gCost < neighbor.G)
                    {
                        neighbor.G = gCost;
                        neighbor.Parent = currentNode;
                    }
                }
            }

            return null; // 没有找到路径
        }

        private List<Node> GetNeighbors(Node node)
        {
            var neighbors = new List<Node>();
            int[] dx = { -1, 1, 0, 0 };
            int[] dy = { 0, 0, -1, 1 };

            for (int i = 0; i < 4; i++)
            {
                int newX = node.X + dx[i];
                int newY = node.Y + dy[i];

                if (newX >= 0 && newX < GridSize && newY >= 0 && newY < GridSize)
                {
                    if (buttons[newX, newY].Background != Brushes.Black) // 不是障碍物
                    {
                        neighbors.Add(new Node(newX, newY));
                    }
                }
            }

            return neighbors;
        }

        private int CalculateHCost(Node current, Node end)
        {
            return Math.Abs(current.X - end.X) + Math.Abs(current.Y - end.Y);
        }

        private List<Node> GetPath(Node endNode)
        {
            var path = new List<Node>();
            var current = endNode;

            while (current != null)
            {
                path.Add(current);
                current = current.Parent;
            }

            path.Reverse();
            return path;
        }

        private void btnSetStart_Click(object sender, RoutedEventArgs e)
        {
            currentMode = "Start";
        }

        private void btnSetEnd_Click(object sender, RoutedEventArgs e)
        {
            currentMode = "End";
        }

        private void btnAddWall_Click(object sender, RoutedEventArgs e)
        {
            currentMode = "Wall";
        }

        private void btnFindPath_Click(object sender, RoutedEventArgs e)
        {
            if (!startPoint.HasValue || !endPoint.HasValue)
            {
                MessageBox.Show("请先设置起点和终点！");
                return;
            }

            // 清除之前的路径
            pathCanvas.Children.Clear();
            for (int i = 0; i < GridSize; i++)
            {
                for (int j = 0; j < GridSize; j++)
                {
                    if (buttons[i, j].Background == Brushes.Blue)
                    {
                        buttons[i, j].Background = Brushes.White;
                    }
                }
            }

            // 重新显示起点和终点
            buttons[(int)startPoint.Value.X, (int)startPoint.Value.Y].Background = Brushes.Green;
            buttons[(int)endPoint.Value.X, (int)endPoint.Value.Y].Background = Brushes.Red;

            // 查找路径
            var path = FindPath(startPoint.Value, endPoint.Value);
            if (path != null)
            {
                DrawPath(path);
            }
            else
            {
                MessageBox.Show("无法找到有效路径！");
            }
        }
        private void DrawPath(List<Node> path)
        {
            if (path.Count < 2) return;

            pathCanvas.Children.Clear();

            var polyline = new Polyline
            {
                Stroke = Brushes.Blue,
                StrokeThickness = 2,
                Points = new PointCollection()
            };

            foreach (var node in path)
            {
                // 直接计算位置，不使用TransformToAncestor
                double x = node.Y * buttonSize + buttonSize / 2; // 注意：这里交换了X和Y
                double y = node.X * buttonSize + buttonSize / 2;
                polyline.Points.Add(new Point(x, y));
            }

            pathCanvas.Children.Add(polyline);
        }

        private void btnClear_Click(object sender, RoutedEventArgs e)
        {
            for (int i = 0; i < GridSize; i++)
            {
                for (int j = 0; j < GridSize; j++)
                {
                    buttons[i, j].Background = Brushes.White;
                }
            }
            startPoint = null;
            endPoint = null;
            currentMode = "";

            // 清除路径线条
            pathCanvas.Children.Clear();
        }
    }

    public class Node
    {
        public int X { get; set; }
        public int Y { get; set; }
        public int G { get; set; } // 从起点到当前节点的代价
        public int H { get; set; } // 从当前节点到终点的预估代价
        public int F => G + H; // 总代价
        public Node Parent { get; set; }

        public Node(int x, int y)
        {
            X = x;
            Y = y;
        }
    }
}
